#pragma once

#include <entt/entt.hpp>
#include <faker/scene/Scene.h>

namespace Faker
{
    struct Entity
    {

        entt::entity m_EntityHandle;
        Faker::Scene *m_Scene = 0;

        Entity() = default;
        Entity(struct Faker::Scene *scene, const entt::entity &e);

        template <typename T, typename... Args>
        T &AddOrReplaceComponent(Args &&...args)
        {
            assert(m_Scene);

            T &component = m_Scene->m_Registry.emplace_or_replace<T>(m_EntityHandle, std::forward<Args>(args)...);
            return component;
        }

        template <typename T>
        T &GetOrEmplaceComponent()
        {

            assert(m_Scene);

            T &component = m_Scene->m_Registry.get_or_emplace<T>(m_EntityHandle);
            return component;
        }

        template <typename T>
        T &GetComponent()
        {
            assert(m_Scene);
            return m_Scene->m_Registry.get<T>(m_EntityHandle);
        }

   
        // get_or_emplace

        template <typename T>
        bool HasComponent()
        {
            // assert(m_Scene);
            if(m_Scene==0)
            {
                return false;
            }
            return m_Scene->m_Registry.any_of<T>(m_EntityHandle);
        }

        template <typename T>
        void RemoveComponent()
        {
            if (m_Scene == 0)
            {
                return;
            }
            m_Scene->m_Registry.remove<T>(m_EntityHandle);
        }
    };
}